#!/bin/bash
# 使用方式：
#   1. 处理文件夹：./transform_to_pbc.sh <目标JS文件夹路径> [PBC输出文件夹路径，可选，默认pbc-test]
#   2. 处理文件列表：./transform_to_pbc.sh -f <文件列表txt>
# 选项：
#   -m, --mode     指定编译模式 (release 或 debug，默认release)
#   --dcheck       启用dcheck检查
#   -f, --file     从指定txt文件读取JS文件路径列表（每行一个JS文件路径，相对路径相对于终端当前目录）
#   -d, --d8-path  指定用于编译生成PBC的d8可执行文件的路径（可选）

# 配置默认值
mode="release"
dcheck=""
PBC_TEST_DIR="./pbc-test"
file_list=""
JS_FOLDER=""
D8_COMPILE=""  # 用于编译生成PBC的d8路径
D8_RUN=""      # 用于运行JS生成结果的d8路径，必须通过环境变量PBC_RUNNER指定

arch="x64"
host=`uname -a`
if [[ ${host} == *"aarch64"* ]]; then
    arch="arm64"
fi

# 存储失败的文件列表
failed_files=()

# 解析命令行参数
parse_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -m|--mode)
                mode="$2"
                shift 2
                ;;
            --dcheck)
                dcheck="-check"
                shift
                ;;
            -f|--file)
                file_list="$2"
                shift 2
                ;;
            -d|--d8-path)  
                D8_COMPILE="$2"
                shift 2
                ;;
            *)
                positional_args+=("$1")
                shift
                ;;
        esac
    done

    if [[ ${#positional_args[@]} -ge 1 && -z "$JS_FOLDER" && -z "$file_list" ]]; then
        JS_FOLDER="${positional_args[0]}"
    fi
    if [[ ${#positional_args[@]} -ge 2 ]]; then
        PBC_TEST_DIR="${positional_args[1]}"
    fi
}

parse_args "$@"

if [[ -n "$JS_FOLDER" && -n "$file_list" ]]; then
    echo "[ERROR] 不能同时指定JS文件夹和文件列表！"
    exit 1
fi

if [[ -z "$JS_FOLDER" && -z "$file_list" ]]; then
    echo "[ERROR] 请传入JS文件夹路径或使用-f指定文件列表！"
    exit 1
fi

if [[ -n "$file_list" ]]; then
    if [[ ! "$file_list" =~ ^/ ]]; then
        file_list="$PWD/$file_list"
    fi
    
    if [ ! -f "$file_list" ]; then
        echo "[ERROR] 文件列表不存在：$file_list"
        exit 1
    fi
    if [ ! -r "$file_list" ]; then
        echo "[ERROR] 没有文件列表的读取权限：$file_list"
        exit 1
    fi
fi

if [[ -n "$JS_FOLDER" ]]; then
    if [[ ! "$JS_FOLDER" =~ ^/ ]]; then
        JS_FOLDER="$PWD/$JS_FOLDER"
    fi
    
    if [ ! -d "$JS_FOLDER" ]; then
        echo "[ERROR] 传入的JS文件夹不存在！路径：$JS_FOLDER"
        exit 1
    fi
fi

if [ ! -d "$PBC_TEST_DIR" ]; then
    mkdir -p "$PBC_TEST_DIR"
    if [ $? -ne 0 ]; then
        echo "[ERROR] 目标目录创建失败！请检查权限。"
        exit 1
    fi
fi

if [ -z "$D8_COMPILE" ]; then
    CI_path=$(realpath $(dirname ${BASH_SOURCE[0]}))
    D8_COMPILE="${CI_path}/../out/${arch}.${mode}${dcheck}/d8"
else
    if [[ ! "$D8_COMPILE" =~ ^/ ]]; then
        D8_COMPILE="$PWD/$D8_COMPILE"
    fi
fi

if [ ! -f "$D8_COMPILE" ] || [ ! -x "$D8_COMPILE" ]; then
    echo "[ERROR] 编译用d8可执行文件不存在或无执行权限！"
    echo "[ERROR] 缺失路径：$(realpath "$D8_COMPILE" 2>/dev/null || echo "$D8_COMPILE")"
    exit 1
fi

if [ -z "$PBC_RUNNER" ]; then
    echo "[ERROR] 未设置PBC_RUNNER环境变量！"
    echo "[ERROR] 请先通过 export PBC_RUNNER=/path/to/d8 命令设置运行用d8路径"
    exit 1
else
    D8_RUN="$PBC_RUNNER"
    if [[ ! "$D8_RUN" =~ ^/ ]]; then
        D8_RUN="$PWD/$D8_RUN"
    fi
fi

if [ ! -f "$D8_RUN" ] || [ ! -x "$D8_RUN" ]; then
    echo "[ERROR] 运行用d8可执行文件不存在或无执行权限！"
    echo "[ERROR] 缺失路径：$(realpath "$D8_RUN" 2>/dev/null || echo "$D8_RUN")"
    exit 1
fi

process_js_file() {
    local js_file="$1"

    if [ ! -f "$js_file" ]; then
        failed_files+=("$js_file (文件不存在)")
        return 1
    fi
    
    if [ ! -r "$js_file" ]; then
        failed_files+=("$js_file (无读取权限)")
        return 1
    fi

    js_filename=$(basename "$js_file" .js)
    pbc_output="$PBC_TEST_DIR/$js_filename.pbc"
    result_output="$PBC_TEST_DIR/$js_filename-result.txt"

    "$D8_COMPILE" --use-pbc --expose-gc "$js_file" --out="$pbc_output" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        "$D8_RUN" --expose-gc "$js_file" > "$result_output" 2>&1
        return 0
    else
        failed_files+=("$js_file (PBC生成失败)")
        return 1
    fi
}

# 输出开始转换的提示
echo "[INFO] 开始转换JS文件到PBC格式..."
echo "[INFO] 输出目录: $(realpath "$PBC_TEST_DIR")"

# 处理JS文件
if [[ -n "$JS_FOLDER" ]]; then
    JS_FOLDER_ABS=$(realpath "$JS_FOLDER")
    echo "[INFO] 处理文件夹: $JS_FOLDER_ABS"
    while IFS= read -r -d '' js_file; do
        process_js_file "$js_file"
    done < <(find "$JS_FOLDER" -type f -name "*.js" -print0)
else
    echo "[INFO] 处理文件列表: $file_list"
    while IFS= read -r line; do
        [[ -z "$line" || "$line" =~ ^# ]] && continue
        if [[ ! "$line" =~ ^/ ]]; then
            js_file="$PWD/$line"
        else
            js_file="$line"
        fi
        
        process_js_file "$js_file"
    done < "$file_list"
fi

# 输出结果
if [ ${#failed_files[@]} -eq 0 ]; then
    echo "All Js Transform To PBC Success"
    exit 0
else
    echo "Failed files:"
    printf '%s\n' "${failed_files[@]}"
    exit 1
fi

